#include "CameraObject.hpp"
#include "CameraManager.hpp"
#include <GL/glut.h>

CameraObject::CameraObject(MVector3D &target, MVector3D &up, MVector3D &right, MVector3D &position, 
						   //float &fov, float &nearPlane, float &farPlane) :
						   float fov, float nearPlane, float farPlane) :
m_cameraID( 0 ),
m_cameraTarget( target ),
m_cameraUpVec( up ),
m_cameraRightVec( right ),
m_cameraPosition( position ),
m_cameraFOV( fov ),
m_nearClipPlane( nearPlane ),
m_farClipPlane( farPlane )
{
	InvalidateView();
}

CameraObject::CameraObject() :
m_cameraID( 0 ),
m_cameraTarget( MVector3D( 0.0f, 0.0f, 0.0f ) ),
m_cameraUpVec( MVector3D( 0.0f, 1.0f, 0.0f ) ),
m_cameraRightVec( MVector3D( 1.0f, 0.0f, 0.0f ) ),
m_cameraPosition( MVector3D( 0.0f, 1.0f, 0.0f ) ),
m_cameraFOV( 45.0f ),
m_nearClipPlane( 1.0f ),
m_farClipPlane( 1000.0f )
{
	InvalidateView();
}

CameraObject::~CameraObject()
{
}

void CameraObject::SetID(int newID)
{
	m_cameraID = newID;
}

const int& CameraObject::GetID() const
{
	return m_cameraID;
}

void CameraObject::Update(clock_t tick)
{
}

void CameraObject::SetTarget(const MVector3D &camTarget)
{
	m_cameraTarget = camTarget;
	InvalidateView();
}

void CameraObject::SetUpVec(const MVector3D &up)
{
	m_cameraUpVec = up;
	InvalidateView();
}

void CameraObject::SetRightVec(const MVector3D &right)
{
	m_cameraRightVec = right;
}

void CameraObject::SetPosition(const MVector3D &position)
{
	m_cameraPosition = position;
	InvalidateView();
}

const MVector3D& CameraObject::GetPosition() const
{
	return m_cameraPosition;
}

const MVector3D& CameraObject::GetTarget() const
{
	return m_cameraTarget;
}

const MVector3D& CameraObject::GetUpVec() const
{
	return m_cameraUpVec;
}

void CameraObject::ActivateCamera()
{
	CameraManager::GetInstance()->SetActiveCamera( m_cameraID );
	InvalidateView();
}

void CameraObject::SetFarClipPlane(const float &farPlane)
{
	m_farClipPlane = farPlane;
	InvalidateView();
}

void CameraObject::SetNearClipPlane(const float &nearPlane)
{
	m_nearClipPlane = nearPlane;
	InvalidateView();
}

void CameraObject::SetFOV(const float &fov)
{
	m_cameraFOV = fov;
	InvalidateView();
}

void CameraObject::InvalidateView()
{
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	gluLookAt( m_cameraPosition.x, m_cameraPosition.y, m_cameraPosition.z,
		m_cameraTarget.x, m_cameraTarget.y, m_cameraTarget.z,
		m_cameraUpVec.x, m_cameraUpVec.y, m_cameraUpVec.z );
}